/**********************************************************************\

 Copyright 2012 Diggory Blake

 This file is part of klip-engine

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.

\**********************************************************************/
#pragma once

#include <Cg/cg.h>

class kEffectCg;
class kEngine;

#include "keffect.h"
#include "kdata.h"
#include "kcommon.h"
#include "kerror.h"

class kEffectCg : public kEffect {
private:
	kEngine* _engine;
	CGeffect _effect;
	CGtechnique _technique;
	CGparameter _textureParams[8];
	std::map<size_t, CGparameter> _semantics;

	void init(CGcontext context, const char* src);

public:
	kEffectCg(kEngine* engine, CGcontext context, const kDataView& source);
	kEffectCg(kEngine* engine, CGcontext context, kStream* source);
	virtual ~kEffectCg();

	inline CGeffect getEffectCg() {
		return _effect;
	}
	inline CGtechnique getTechniqueCg() {
		return _technique;
	}
	virtual kHandle getParamHandle(const std::tstring& name);
	virtual void setParam(kHandle handle, size_t n, const int* v);
	virtual void setParam(kHandle handle, size_t n, const float* v);
	virtual void unsetParam(kHandle handle);
	inline CGparameter getTextureParam(size_t index) {
		if (index >= 8) {
			throw kError(_T("Index out of range!"));
		}

		return _textureParams[index];
	}
	inline void addSemantic(size_t index, const std::tstring& name) {
		kHandle handle = getParamHandle(name);
		if (handle)
			_semantics[index] = (CGparameter)handle;
	}
	inline void removeSemantic(size_t index) {
		_semantics.erase(index);
	}
	inline const std::map<size_t, CGparameter>& getSemantics() {
		return _semantics;
	}
};
